#pragma once
#ifndef __HWINCOMCONTROL_H__
#define __HWINCOMCONTROL_H__

#include "hwincontrol.h"
#include "hwincomobject.h"

namespace harlinn
{
    namespace windows
    {
        class ComControl : public ComObject,
            IOleControlImpl<ComControl>,
            IOleObjectImpl<ComControl>,
            IOleInPlaceObjectImpl<ComControl>,
            IOleInPlaceActiveObjectImpl<ComControl>,
            IViewObject2Impl<ComControl>,
            IPersistStreamInitImpl<ComControl>,
            IPersistPropertyBagImpl<ComControl>,
            IPersistStorageImpl<ComControl>,
            IQuickActivateImpl<ComControl>,
            IDropTargetImpl<ComControl>,
            IDropSourceImpl<ComControl>
        {
            

            OleClientSite oleClientSite;

        public:
            typedef ComObject Base;
            ComControl( std::shared_ptr<Control> theControl )
                : Base(theControl),
                  IOleControlImpl<ComControl>(this),
                  IOleObjectImpl<ComControl>(this),
                  IOleInPlaceObjectImpl<ComControl>(this),
                  IOleInPlaceActiveObjectImpl<ComControl>(this),
                  IViewObject2Impl<ComControl>(this),
                  IPersistStreamInitImpl<ComControl>(this),
                  IPersistPropertyBagImpl<ComControl>(this),
                  IPersistStorageImpl<ComControl>(this),
                  IQuickActivateImpl<ComControl>(this),
                  IDropTargetImpl<ComControl>(this),
                  IDropSourceImpl<ComControl>(this)
            {}

            virtual HRESULT QueryInterface( REFIID riid,void ** ppvObject)
            {
                return Base::QueryInterface( riid,ppvObject);
            }

            virtual ULONG STDMETHODCALLTYPE AddRef( )
            {
                return Base::AddRef( );
            }

            virtual ULONG STDMETHODCALLTYPE Release( )
            {
                return Base::Release( );
            }


            std::shared_ptr<Control> GetControl() const
            {
                return InternalObject<Control>();
            }

            // IOleControl
            HWIN_EXPORT HRESULT GetControlInfo(CONTROLINFO *pCI);
            HWIN_EXPORT HRESULT OnMnemonic(MSG *pMsg);
            HWIN_EXPORT HRESULT OnAmbientPropertyChange(DISPID dispID);
            HWIN_EXPORT HRESULT FreezeEvents(BOOL bFreeze);

            // IOleObject
            HWIN_EXPORT HRESULT SetClientSite(IOleClientSite *pClientSite);
            HWIN_EXPORT HRESULT GetClientSite(IOleClientSite **ppClientSite);
            HWIN_EXPORT HRESULT SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj);
            HWIN_EXPORT HRESULT Close(DWORD dwSaveOption );
            HWIN_EXPORT HRESULT SetMoniker(DWORD dwWhichMoniker,IMoniker *pmk);
            HWIN_EXPORT HRESULT GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
            HWIN_EXPORT HRESULT InitFromData( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved);
            HWIN_EXPORT HRESULT GetClipboardData( DWORD dwReserved, IDataObject **ppDataObject);
            HWIN_EXPORT HRESULT DoVerb( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect);
            HWIN_EXPORT HRESULT EnumVerbs( IEnumOLEVERB **ppEnumOleVerb );
            HWIN_EXPORT HRESULT Update( );
            HWIN_EXPORT HRESULT IsUpToDate( );
            HWIN_EXPORT HRESULT GetUserClassID( CLSID *pClsid);
            HWIN_EXPORT HRESULT GetUserType( DWORD dwFormOfType,LPOLESTR *pszUserType);
            HWIN_EXPORT HRESULT SetExtent( DWORD dwDrawAspect,SIZEL *psizel);
            HWIN_EXPORT HRESULT GetExtent( DWORD dwDrawAspect,SIZEL *psizel);
            HWIN_EXPORT HRESULT Advise( IAdviseSink *pAdvSink,DWORD *pdwConnection);
            HWIN_EXPORT HRESULT Unadvise( DWORD dwConnection);
            HWIN_EXPORT HRESULT EnumAdvise( IEnumSTATDATA **ppenumAdvise);
            HWIN_EXPORT HRESULT GetMiscStatus( DWORD dwAspect, DWORD *pdwStatus);
            HWIN_EXPORT HRESULT SetColorScheme( LOGPALETTE *pLogpal);

            // IOleInPlaceObject
            HWIN_EXPORT HRESULT InPlaceDeactivate( );
            HWIN_EXPORT HRESULT UIDeactivate( );
            HWIN_EXPORT HRESULT SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect);
            HWIN_EXPORT HRESULT ReactivateAndUndo( );

            // IOleInPlaceActiveObject
            HWIN_EXPORT HRESULT TranslateAccelerator(LPMSG lpmsg);
            HWIN_EXPORT HRESULT OnFrameWindowActivate(BOOL fActivate);
            HWIN_EXPORT HRESULT OnDocWindowActivate( BOOL fActivate);
            HWIN_EXPORT HRESULT ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow);
            HWIN_EXPORT HRESULT EnableModeless(BOOL fEnable);

            // IOleWindow
            HWIN_EXPORT HRESULT GetWindow(HWND *phwnd);
            HWIN_EXPORT HRESULT ContextSensitiveHelp(BOOL fEnterMode);

            // IViewObject
            HWIN_EXPORT HRESULT Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue), ULONG_PTR dwContinue);
            HWIN_EXPORT HRESULT GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet);
            HWIN_EXPORT HRESULT Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
            HWIN_EXPORT HRESULT Unfreeze( DWORD dwFreeze);
            HWIN_EXPORT HRESULT SetAdvise( DWORD aspects,DWORD advf,IAdviseSink *pAdvSink);
            HWIN_EXPORT HRESULT GetAdvise( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink);

            // IViewObject2
            HWIN_EXPORT HRESULT GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel);

            // IPersist
            HWIN_EXPORT HRESULT GetClassID(CLSID *pClassID);

            // IPersistStreamInit
            HWIN_EXPORT HRESULT IsDirty( );
            HWIN_EXPORT HRESULT Load( LPSTREAM pStm);
            HWIN_EXPORT HRESULT Save( LPSTREAM pStm, BOOL fClearDirty);
            HWIN_EXPORT HRESULT GetSizeMax(ULARGE_INTEGER *pCbSize);
            HWIN_EXPORT HRESULT InitNew( );

            // IPersistPropertyBag
            HWIN_EXPORT HRESULT Load( IPropertyBag *pPropBag, IErrorLog *pErrorLog);
            HWIN_EXPORT HRESULT Save( IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);

            // IPersistStorage
            HWIN_EXPORT HRESULT InitNew(IStorage *pStg);
            HWIN_EXPORT HRESULT Load(IStorage *pStg );
            HWIN_EXPORT HRESULT Save( IStorage *pStgSave, BOOL fSameAsLoad);
            HWIN_EXPORT HRESULT SaveCompleted( IStorage *pStgNew);
            HWIN_EXPORT HRESULT HandsOffStorage( );

            // IQuickActivate
            HWIN_EXPORT HRESULT QuickActivate( QACONTAINER *pQaContainer, QACONTROL *pQaControl);
            HWIN_EXPORT HRESULT SetContentExtent(LPSIZEL pSizel);
            HWIN_EXPORT HRESULT GetContentExtent(LPSIZEL pSizel);

            // IDropTarget
            HWIN_EXPORT HRESULT DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
            HWIN_EXPORT HRESULT DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
            HWIN_EXPORT HRESULT DragLeave( );
            HWIN_EXPORT HRESULT Drop( IDataObject *pDataObj,DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);

            // IDropSource
            HWIN_EXPORT HRESULT QueryContinueDrag( BOOL fEscapePressed, DWORD grfKeyState);
            HWIN_EXPORT HRESULT GiveFeedback( DWORD dwEffect);

        };
    };
};

#endif // __HWINCOMCONTROL_H__


